package chapter21.chapter21_9;//: concurrency/FastSimulation.java

import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.*;

import static net.mindview.util.Print.*;

public class FastSimulation {
    static final int N_ELEMENTS = 100000;
    static final int N_GENES = 30;
    static final int N_EVOLVERS = 50;
    static final AtomicInteger[][] GRID =
            new AtomicInteger[N_ELEMENTS][N_GENES];
    static Random rand = new Random(47);

    static class Evolver implements Runnable {
        public void run() {
            while (!Thread.interrupted()) {
                // Randomly select an element to work on:
                int element = rand.nextInt(N_ELEMENTS);
                for (int i = 0; i < N_GENES; i++) {
                    int previous = element - 1;
                    if (previous < 0) previous = N_ELEMENTS - 1;
                    int next = element + 1;
                    if (next >= N_ELEMENTS) next = 0;
                    int oldvalue = GRID[element][i].get();
                    // Perform some kind of modeling calculation:
                    int newvalue = oldvalue +
                            GRID[previous][i].get() + GRID[next][i].get();
                    newvalue /= 3; // Average the three values
                    if (!GRID[element][i]
                            .compareAndSet(oldvalue, newvalue)) {
                        // Policy here to deal with failure. Here, we
                        // just report it and ignore it; our model
                        // will eventually deal with it.
                        print("Old value changed from " + oldvalue);
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < N_ELEMENTS; i++)
            for (int j = 0; j < N_GENES; j++)
                GRID[i][j] = new AtomicInteger(rand.nextInt(1000));
        for (int i = 0; i < N_EVOLVERS; i++)
            exec.execute(new Evolver());
        TimeUnit.SECONDS.sleep(5);
        exec.shutdownNow();
    }
} /*

Old value changed from 542
Old value changed from 802
Old value changed from 684
Old value changed from 800
Old value changed from 710
Old value changed from 50
Old value changed from 427
Old value changed from 249
Old value changed from 397
Old value changed from 406
Old value changed from 487
Old value changed from 448
Old value changed from 465
Old value changed from 413
Old value changed from 338
Old value changed from 367
Old value changed from 394
Old value changed from 469
Old value changed from 428
Old value changed from 337
Old value changed from 527
Old value changed from 674
Old value changed from 309
Old value changed from 396
Old value changed from 539
Old value changed from 443
Old value changed from 734
Old value changed from 554
Old value changed from 622
Old value changed from 444
Old value changed from 436
Old value changed from 506
Old value changed from 411
Old value changed from 638
Old value changed from 536
Old value changed from 489
Old value changed from 357
Old value changed from 564
Old value changed from 579
Old value changed from 628
Old value changed from 460
Old value changed from 588
Old value changed from 679
Old value changed from 516
Old value changed from 542
Old value changed from 603
Old value changed from 459
Old value changed from 471
Old value changed from 467
Old value changed from 371
Old value changed from 509
Old value changed from 498
Old value changed from 442
Old value changed from 414
Old value changed from 496
Old value changed from 461
Old value changed from 473
Old value changed from 465
Old value changed from 481
Old value changed from 435
Old value changed from 448
Old value changed from 451
Old value changed from 417
Old value changed from 461
Old value changed from 546
Old value changed from 413
Old value changed from 470
Old value changed from 413
Old value changed from 370
Old value changed from 568
Old value changed from 585
Old value changed from 531
Old value changed from 493
Old value changed from 544
Old value changed from 294
Old value changed from 554
Old value changed from 597
Old value changed from 514
Old value changed from 686
Old value changed from 594
Old value changed from 583
Old value changed from 624
Old value changed from 291
Old value changed from 619
Old value changed from 439
Old value changed from 229
Old value changed from 329
Old value changed from 548
Old value changed from 498
Old value changed from 530
Old value changed from 404
Old value changed from 526
Old value changed from 397
Old value changed from 576
Old value changed from 575
Old value changed from 363
Old value changed from 623
Old value changed from 559
Old value changed from 681
Old value changed from 500
Old value changed from 533
Old value changed from 432
Old value changed from 571
Old value changed from 532
Old value changed from 463
Old value changed from 535
Old value changed from 404
Old value changed from 466
Old value changed from 311
Old value changed from 543
Old value changed from 425
Old value changed from 478
Old value changed from 536
Old value changed from 573
Old value changed from 656
Old value changed from 339
Old value changed from 526
Old value changed from 517
Old value changed from 557
Old value changed from 416
Old value changed from 538
Old value changed from 536
Old value changed from 478
Old value changed from 462
Old value changed from 598
Old value changed from 500
Old value changed from 523
Old value changed from 426
Old value changed from 502
Old value changed from 422
Old value changed from 491
Old value changed from 528
Old value changed from 472
Old value changed from 466
Old value changed from 551
Old value changed from 506
Old value changed from 520
Old value changed from 546
Old value changed from 454
Old value changed from 416
Old value changed from 389
Old value changed from 432
Old value changed from 519
Old value changed from 398
Old value changed from 605
Old value changed from 528
Old value changed from 518
Old value changed from 269
Old value changed from 524
Old value changed from 361
Old value changed from 412
Old value changed from 499
Old value changed from 447
Old value changed from 516
Old value changed from 532
Old value changed from 595
Old value changed from 363
Old value changed from 486
Old value changed from 542
Old value changed from 558
Old value changed from 497
Old value changed from 571
Old value changed from 377
Old value changed from 494
Old value changed from 515
Old value changed from 409
Old value changed from 621
Old value changed from 499
Old value changed from 451
Old value changed from 437
Old value changed from 490
Old value changed from 490
Old value changed from 477
Old value changed from 533
Old value changed from 464
Old value changed from 568
Old value changed from 447
Old value changed from 424
Old value changed from 581
Old value changed from 453
Old value changed from 366
Old value changed from 421
Old value changed from 498
Old value changed from 459
Old value changed from 546
Old value changed from 503
Old value changed from 626
Old value changed from 456
Old value changed from 527
Old value changed from 630
Old value changed from 506
Old value changed from 561
Old value changed from 499
Old value changed from 549
Old value changed from 545
Old value changed from 586
Old value changed from 429
Old value changed from 554
Old value changed from 465
Old value changed from 548
Old value changed from 553
Old value changed from 336
Old value changed from 481
Old value changed from 577
Old value changed from 494
Old value changed from 388*///:~
